package papacharly.encheres.dao;


import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import papacharly.encheres.log.Logger;

/**
 * Classe de gestion de la configuration et de la session Hibernate.
 * Fournie la <code>Session</code> Hibernate. *
 */
public class ConnectionFactory {

    static Logger log = new Logger(ConnectionFactory.class.getCanonicalName());
    private static ConnectionFactory instance = null;
    private static Configuration configuration = null;
    private static SessionFactory sessionFactory = null;
    public static final ThreadLocal session = new ThreadLocal();

    private ConnectionFactory() {
        createNewSessionFactory();
    }

    /**
     * Create a new sessionFactory
     * @return la sessionFactory créée
     */
    private static SessionFactory createNewSessionFactory() {
        try {
            if (sessionFactory == null) {
//                if (configuration == null) {
//                    configuration = new Configuration();
//                    configuration = new AnnotationConfiguration().configure().buildSessionFactory();
//                    configuration.addResource("papacharly/encheres/model/Categorie.hbm.xml");
//                    configuration.addResource("papacharly/encheres/model/Enchere.hbm.xml");
//                    configuration.addResource("papacharly/encheres/model/Produit.hbm.xml");
//                    configuration.addResource("papacharly/encheres/model/User.hbm.xml");
//                }

//                sessionFactory = configuration.buildSessionFactory();
                sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
            }
        } catch (MappingException e) {
            /*
             * Upon encountering a Hibernate generated Exception, we are throwing
             * an unchecked RuntimeExcpetion that will cause the user's
             * request to fail.
             *
             */
            log.error("Mapping Exception" + e.getMessage());
            throw new RuntimeException(e);
        } catch (HibernateException e) {
            /*
             * Upon encountering a Hibernate generated Exception, we are throwing
             * an unchecked RuntimeExcpetion that will cause the user's request to fail.
             *
             */
            log.error("Hibernate Exception" + e.getMessage());
            throw new RuntimeException(e);
        }


        return sessionFactory;
    }

    /**
     * getInstance() returns the instance of the ConnectionFactory singleton.
     *
     * Example call to retrieve session:
     *
     * <pre>
     * Session session = ConnectionFactory.getInstance().getSession();
     * </pre>
     *
     * @return Instance of the <code>ConnectionFactory</code> singleton.
     */
    public static synchronized ConnectionFactory getInstance() {
        /*
         * If the instance of the Singleton has not been created, create and
         * return.
         */
        if (instance == null) {
            instance = new ConnectionFactory();
        }
        return instance;
    }

    /**
     * getSession() returns a Hibernate <code>Session</code>
     *
     * @return <code>Session</code> retrieved from Hibernate <Code>SessionFactory</code>
     */
    public static synchronized Session getSession() {

        try {

            Session s = (Session) session.get();
            // Ouvre une nouvelle Session, si ce Thread n'en a aucune
            if (s == null) {
                if (sessionFactory == null) {
                    createNewSessionFactory();
                }
                s = sessionFactory.openSession();
                session.set(s);
            }
            return s;

        } catch (HibernateException e) {
            /*
             * Upon encountering a Hibernate generated Exception, we are throwing
             * an unchecked RuntimeExcpetion that will cause the user's request to fail.
             *
             */
            log.error("Mapping Exception" + e.getMessage());
            throw new RuntimeException(e);
        }
    }

    public static synchronized void closeSession() {
        try {
            Session s = (Session) session.get();
            session.set(null);
            if (s != null) {
                s.close();
            }
        } catch (HibernateException e) {
            log.warn("Une erreur est survenue lors de la fermeture de la session hibernate");
        }
    }
}
